library(chillR)
library(LarsChill)
library(evalpheno)
library(tidyverse)
#prepare temperature data
zaragoza <- read.csv('data/zaragoza_clean.csv') %>%
chillR::stack_hourly_temps(latitude = 41.65) %>%
purrr::pluck('hourtemps') %>%
chillR::genSeasonList(years = 1974:2022) %>%
setNames(paste0('Zaragoza.',1974:2022))
cieza <- read.csv('data/cieza_clean.csv') %>%
chillR::stack_hourly_temps(latitude = 38.24) %>%
purrr::pluck('hourtemps') %>%
chillR::genSeasonList(years = 1996:2022) %>%
setNames(paste0('Cieza.', 1996:2022))
seasonlist <- c(cieza, zaragoza)
rm(cieza, zaragoza)
apricot_master <- read.csv('data/master_apricot.csv')
#par file
fname <- 'data/par-apricot.csv'
#-----------------------#
#combined fitting #
#-----------------------#
for(ncali in unique(apricot_master$ncal)){
if(file.exists(fname)){
res <- read.csv(fname)
if(any(res$n_cal == ncali & res$fit == 'combined')) next()
}
n_cult <- apricot_master$cultivar %>% unique() %>% length()
#choose different starting point
# yc zc s1 Tu theta_c tau pie_c Tf Tb slope
x_0 <- c(rep(21.3952307,n_cult), rep(404.5477002,n_cult), rep(0.8639453,n_cult), 15.6854627, 286.7333573, 37.6044377, 24.0478411, 7.3577423, 9.2680642, 4.6845785)
x_U <- c(rep(80,n_cult), rep(700,n_cult), rep(1.2,n_cult), 30, 287, 48, 50, 10, 10, 5.00)
x_L <- c(rep(5,n_cult), rep(100,n_cult), rep(0.1,n_cult), 15, 286, 16, 24, 2, 0, 1.2)
#limits for the inequality constraints
# #gdh parameters #q10 for E0 and E1
c_L <- c( 0, 0, 0, 1.5, 1.5)
c_U <- c(Inf, Inf, Inf, 3.5, 3.5)
problem<-list(f="eval_phenoflex_combined",
x_0 = x_0,
x_L = x_L,
x_U = x_U,
c_L = c_L,
c_U = c_U)
#you can control the maximum time of running or max number of iterations
#options for fitter
opts<-list(maxeval = 50000,
#maxeval = 1000,
#maxtime = 60 * 30,
local_solver = 'DHC',
local_bestx = 1,
inter_save = 0,
plot = 1)
Tc <- 36
theta_star <- 279
sub <- apricot_master %>%
filter(ncal == ncali) %>%
filter(split == 'Calibration') %>%
mutate(loc.year = paste(location, year, sep ='.'))
bloomlist_train <- purrr::map(unique(sub$cultivar), function(cult){
sub %>%
filter(cultivar == cult) %>%
pull(yday)
})
seasonlist_train <- purrr::map(unique(sub$cultivar), function(cult){
sub %>%
filter(cultivar == cult) %>%
pull(loc.year) %>%
seasonlist[.]
})
set.seed(123456789)
res_list <- LarsChill::custom_essr(problem = problem,
opts,
modelfn = custom_PhenoFlex_GDHwrapper,
bloomJDays = bloomlist_train,
SeasonList = seasonlist_train,
ncult = n_cult)
location <- c()
for(cult in unique(sub$cultivar)){
l <- sub %>%
filter(cultivar == cult) %>%
pull(location) %>%
unique()
location <- c(location,l)
}
#save outcome in a table, append the table
data.frame(cultivar = unique(sub$cultivar),
location = location,
yc = res_list$xbest[1:n_cult],
zc = res_list$xbest[(n_cult+1):(n_cult*2)],
s1 = res_list$xbest[(n_cult*2+1):(n_cult*3)],
Tu = res_list$xbest[n_cult*3+1],
theta_star = theta_star,
theta_c = res_list$xbest[n_cult*3+2],
tau = res_list$xbest[n_cult*3+3],
pie_c = res_list$xbest[n_cult*3+4],
Tf = res_list$xbest[n_cult*3+5],
Tc = Tc,
Tb = res_list$xbest[n_cult*3+6],
slope = res_list$xbest[n_cult*3+7],
E0 = NA,
E1 = NA,
A0 = NA,
A1 = NA,
fit = 'combined',
n_cal = ncali) %>%
write.table(file = fname,
append = TRUE,
row.names = FALSE,
sep = ',',
col.names=!file.exists(fname))
}
#--------------------#
#single fitting #
#--------------------#
# yc zc s1 Tu theta_c tau pie_c Tf Tb slope
x_0 <- c(21.3952307, 404.5477002, 0.8639453, 15.6854627, 286.7333573, 37.6044377, 24.0478411, 7.3577423, 9.2680642, 4.6845785)
x_U <- c(80, 700, 1.2, 30, 287, 48, 50, 10, 10, 5.00)
x_L <- c(5, 100, 0.1, 15, 286, 16, 24, 2, 0, 1.2)
#limits for the inequality constraints
# #gdh parameters #q10 for E0 and E1
c_L <- c( 0, 0, 0, 1.5, 1.5)
c_U <- c(Inf, Inf, Inf, 3.5, 3.5)
evalfun <- evalpheno::eval_phenoflex_single_twofixed
problem<-list(f="evalfun",
x_0 = x_0,
x_L = x_L,
x_U = x_U,
c_L = c_L,
c_U = c_U)
#you can control the maximum time of running or max number of iterations
#options for fitter
opts<-list(maxeval = 30000,
#maxtime = 60 * 30,
local_solver = 'DHC',
local_bestx = 1,
inter_save = 0,
plot = 1)
Tc <- 36
theta_star <- 279
# cult <- unique(pheno_master$cultivar)[1]
# ncal_i <- c('full', 'scarce')[1]
# i <- unique(apricot_master$repetition)[1]
for(ncali in unique(apricot_master$ncal)){
for(cult in unique(apricot_master$cultivar)){
if(file.exists(fname)){
res <- read.csv(fname)
if(any(res$n_cal == ncali &
res$cultivar == cult &
res$fit == 'single')) next()
}
sub <- apricot_master %>%
filter(cultivar == cult) %>%
filter(ncal == ncali) %>%
filter(split == 'Calibration') %>%
mutate(loc.year = paste(location, year, sep ='.'))
loc <- unique(sub$location)
set.seed(123456789)
res_list <- custom_essr(problem = problem,
opts,
modelfn = custom_PhenoFlex_GDHwrapper,
bloomJDays = sub$yday,
SeasonList = seasonlist[as.character(sub$loc.year)],
Tc = Tc,
theta_star = theta_star)
#save outcome in a table, append the table
data.frame(cultivar = cult,
location = loc,
yc = res_list$xbest[1],
zc = res_list$xbest[2],
s1 = res_list$xbest[3],
Tu = res_list$xbest[4],
theta_star = theta_star,
theta_c = res_list$xbest[5],
tau = res_list$xbest[6],
pie_c = res_list$xbest[7],
Tf = res_list$xbest[8],
Tc = Tc,
Tb = res_list$xbest[9],
slope = res_list$xbest[10],
E0 = NA,
E1 = NA,
A0 = NA,
A1 = NA,
fit = 'single',
n_cal = ncali) %>%
write.table(file = fname,
append = TRUE,
row.names = FALSE,
sep = ',',
col.names=!file.exists(fname))
}
}
#--------------------#
#baseline fitting #
#--------------------#
for(ncali in unique(apricot_master$ncal)){
#calibrate baseline (with dynamic model paraemters)
par_names <- c( 'yc', 'zc', 's1', 'Tu', 'theta_star', 'theta_c', 'tau', 'pie_c', 'Tf', 'Tc', 'Tb', 'slope')
par_names_old <- par_names
par_names_old[5:8] <- c('E0', 'E1', 'A0', 'A1')
evalfun <- evalpheno::eval_phenoflex_onlyreq
# Tu E0 E1 A0 A1 Tf Tc Tb slope
par_fixed <- c(25, 4153.5, 12888.8, 139500, 2.567e+18, 4, 36, 4, 1.6)
#took values of ferragnes repetition 1 from adamedor as starting point
x_0 <- c(21.3952307, 404.5477002, 0.8639453)
x_U <- c(80, 700, 1.2)
x_L <- c(5, 100, 0.1)
#limits for the inequality constraints
# #gdh parameters #q10 for E0 and E1
c_L <- c( 0, 0, 0, 0, 0)
c_U <- c(Inf, Inf, Inf, Inf, Inf)
problem<-list(f="evalfun",
x_0 = x_0,
x_L = x_L,
x_U = x_U,
c_L = c_L,
c_U = c_U)
#you can control the maximum time of running or max number of iterations
#options for fitter
opts<-list(maxeval = 5000,
#maxtime = 60 * 30,
local_solver = 'DHC',
local_bestx = 1,
inter_save = 0,
plot = 1)
Tc <- 36
theta_star <- 279
# cult <- unique(apricot_master$cultivar)[1]
# ncal_i <- c('full', 'scarce')[1]
# i <- unique(apricot_master$repetition)[1]
for(cult in unique(apricot_master$cultivar)){
if(file.exists(fname)){
res <- read.csv(fname)
if(any(res$n_cal == ncali &
res$cultivar == cult &
res$fit == 'baseline')) next()
}
sub <- apricot_master %>%
filter(cultivar == cult) %>%
filter(ncal == ncali) %>%
filter(split == 'Calibration') %>%
mutate(loc.year = paste(location, year, sep ='.'))
loc <- unique(sub$location)
set.seed(123456789)
res_list <- LarsChill::custom_essr(problem = problem,
opts,
modelfn = evalpheno::custom_PhenoFlex_GDHwrapper,
bloomJDays = sub$yday,
SeasonList = seasonlist[as.character(sub$loc.year)],
par_fixed = par_fixed)
#save outcome in a table, append the table
data.frame(cultivar = cult,
location = loc,
yc = res_list$xbest[1],
zc = res_list$xbest[2],
s1 = res_list$xbest[3],
Tu = par_fixed[1],
theta_star = NA,
theta_c = NA,
tau = NA,
pie_c = NA,
Tf = par_fixed[6],
Tc = par_fixed[7],
Tb = par_fixed[8],
slope = par_fixed[9],
E0 = par_fixed[2],
E1 = par_fixed[3],
A0 = par_fixed[4],
A1 = par_fixed[5],
fit = 'baseline',
n_cal = ncali) %>%
write.table(file = fname,
append = TRUE,
row.names = FALSE,
sep = ',',
col.names=!file.exists(fname))
}
}The structure is similar to the calibration of almonds.
In [1]: